﻿using System;
using System.Collections.Generic;

namespace D3crft.Characters.ClassObjects {
    public class ocCharacter {

        // Enums, Delegates, Events

        public enum eCharacterClass { Barbarian, Crusader, Demon_Hunter, Monk, Wizard, Witch_Doctor, Unknown };

        public delegate void CharacterEventHandler(object oSender, CharacterEventArgs eaCharacter);

        // Static methods

        public static eCharacterClass GetClassEnumeration(string sName) {
            switch (sName.ToLower()) {
                case "barbarian":
                    return eCharacterClass.Barbarian;
                case "crusader":
                    return eCharacterClass.Crusader;
                case "demon hunter":
                    return eCharacterClass.Demon_Hunter;
                case "demon_hunter":
                    return eCharacterClass.Demon_Hunter;
                case "monk":
                    return eCharacterClass.Monk;
                case "wizard":
                    return eCharacterClass.Wizard;
                case "witch doctor":
                    return eCharacterClass.Witch_Doctor;
                case "witch_doctor":
                    return eCharacterClass.Witch_Doctor;
                default:
                    return eCharacterClass.Unknown;
            }
        }

        public static string GetClassString(eCharacterClass eClass) {
            switch (eClass) {
                case eCharacterClass.Barbarian:
                    return "Barbarian";
                case eCharacterClass.Crusader:
                    return "Crusader";
                case eCharacterClass.Demon_Hunter:
                    return "Demon Hunter";
                case eCharacterClass.Monk:
                    return "Monk";
                case eCharacterClass.Witch_Doctor:
                    return "Witch Doctor";
                case eCharacterClass.Wizard:
                    return "Wizard";
                default:
                    return "Unknown";
            }
        }

        public static bool CompareCharacter(ocCharacter oCharacterOne, ocCharacter oCharacterTwo) {
            bool bTemp = true;

            if (oCharacterOne.sID != oCharacterTwo.sID) {
                bTemp = false;
            }
            else if (oCharacterOne.sName != oCharacterTwo.sName) {
                bTemp = false;
            }
            else if (oCharacterOne.eClass != oCharacterTwo.eClass) {
                bTemp = false;
            }
            else if (oCharacterOne.iBaseStat_Strength != oCharacterTwo.iBaseStat_Strength) {
                bTemp = false;
            }
            else if (oCharacterOne.iBaseStat_Dexterity != oCharacterTwo.iBaseStat_Dexterity) {
                bTemp = false;
            }
            else if (oCharacterOne.iBaseStat_Intelligence != oCharacterTwo.iBaseStat_Intelligence) {
                bTemp = false;
            }
            else if (oCharacterOne.iBaseStat_Vitality != oCharacterTwo.iBaseStat_Vitality) {
                bTemp = false;
            }
            else if (oCharacterOne.fOffStat_AttackSpeedInrease != oCharacterTwo.fOffStat_AttackSpeedInrease) {
                bTemp = false;
            }
            else if (oCharacterOne.fOffStat_CritChance != oCharacterTwo.fOffStat_CritChance) {
                bTemp = false;
            }
            else if (oCharacterOne.fOffStat_CritDamage != oCharacterTwo.fOffStat_CritDamage) {
                bTemp = false;
            }
            else if (oCharacterOne.iOffStat_BonusDamage_Min != oCharacterTwo.iOffStat_BonusDamage_Min) {
                bTemp = false;
            }
            else if (oCharacterOne.iOffStat_BonusDamage_Max != oCharacterTwo.iOffStat_BonusDamage_Max) {
                bTemp = false;
            }
            else if (oCharacterOne.fWeaponStats_MHDPS != oCharacterTwo.fWeaponStats_MHDPS) {
                bTemp = false;
            }
            else if (oCharacterOne.fWeaponStats_MHAPS != oCharacterTwo.fWeaponStats_MHAPS) {
                bTemp = false;
            }
            else if (oCharacterOne.eClass == eCharacterClass.Barbarian) {
                if (((ocBarbarian)oCharacterOne).bWeaponStat_Dualwield != ((ocBarbarian)oCharacterTwo).bWeaponStat_Dualwield) {
                    bTemp = false;
                }
                else if (((ocBarbarian)oCharacterOne).fWeaponStats_OHDPS != ((ocBarbarian)oCharacterTwo).fWeaponStats_OHDPS) {
                    bTemp = false;
                }
                else if (((ocBarbarian)oCharacterOne).fWeaponStats_OHAPS != ((ocBarbarian)oCharacterTwo).fWeaponStats_OHAPS) {
                    bTemp = false;
                }
            }
            else if (oCharacterOne.eClass == eCharacterClass.Demon_Hunter) {
                if (((ocDemonHunter)oCharacterOne).bWeaponStat_Dualwield != ((ocDemonHunter)oCharacterTwo).bWeaponStat_Dualwield) {
                    bTemp = false;
                }
                else if (((ocDemonHunter)oCharacterOne).fWeaponStats_OHDPS != ((ocDemonHunter)oCharacterTwo).fWeaponStats_OHDPS) {
                    bTemp = false;
                }
                else if (((ocDemonHunter)oCharacterOne).fWeaponStats_OHAPS != ((ocDemonHunter)oCharacterTwo).fWeaponStats_OHAPS) {
                    bTemp = false;
                }
            }
            else if (oCharacterOne.eClass == eCharacterClass.Monk) {
                if (((ocMonk)oCharacterOne).bWeaponStat_Dualwield != ((ocMonk)oCharacterTwo).bWeaponStat_Dualwield) {
                    bTemp = false;
                }
                else if (((ocMonk)oCharacterOne).fWeaponStats_OHDPS != ((ocMonk)oCharacterTwo).fWeaponStats_OHDPS) {
                    bTemp = false;
                }
                else if (((ocMonk)oCharacterOne).fWeaponStats_OHAPS != ((ocMonk)oCharacterTwo).fWeaponStats_OHAPS) {
                    bTemp = false;
                }
            }
            if (oCharacterOne.iOtherStat_PhysicalBonus != oCharacterTwo.iOtherStat_PhysicalBonus) {
                bTemp = false;
            }
            else if (oCharacterOne.iOtherStat_ArcaneBonus != oCharacterTwo.iOtherStat_ArcaneBonus) {
                bTemp = false;
            }
            else if (oCharacterOne.iOtherStat_ColdBonus != oCharacterTwo.iOtherStat_ColdBonus) {
                bTemp = false;
            }
            else if (oCharacterOne.iOtherStat_FireBonus != oCharacterTwo.iOtherStat_FireBonus) {
                bTemp = false;
            }
            else if (oCharacterOne.iOtherStat_HolyBonus != oCharacterTwo.iOtherStat_HolyBonus) {
                bTemp = false;
            }
            else if (oCharacterOne.iOtherStat_LighteningBonus != oCharacterTwo.iOtherStat_LighteningBonus) {
                bTemp = false;
            }
            else if (oCharacterOne.iOtherStat_PoisonBonus != oCharacterTwo.iOtherStat_PoisonBonus) {
                bTemp = false;
            }


            return bTemp;
        }

        ////// Members

        // overhead
        public string sID = "";
        public string sName = "";
        public eCharacterClass eClass = eCharacterClass.Unknown;
        // Base stats
        public int iBaseStat_Strength = 1;
        public int iBaseStat_Dexterity = 1;
        public int iBaseStat_Intelligence = 1;
        public int iBaseStat_Vitality = 1;
        // Offstats
        public float fOffStat_AttackSpeedInrease = 0.0f;
        public float fOffStat_CritChance = 5.0f;
        public float fOffStat_CritDamage = 50.0f;
        public int iOffStat_BonusDamage_Min = 0;
        public int iOffStat_BonusDamage_Max = 0;
        // Weapon stats
        public float fWeaponStats_MHDPS = 100.0f;
        public float fWeaponStats_MHAPS = 1.0f;
        // Other stats
        public int iOtherStat_PhysicalBonus = 0;
        public int iOtherStat_ArcaneBonus = 0;
        public int iOtherStat_ColdBonus = 0;
        public int iOtherStat_FireBonus = 0;
        public int iOtherStat_HolyBonus = 0;
        public int iOtherStat_LighteningBonus = 0;
        public int iOtherStat_PoisonBonus = 0;

        public int[] iActiveSkills = new int[6];
        public int[] iPassiveSkills = new int[4];

        // Class methods

        public ocCharacter GetCopy() {
            ocCharacter oCharacter;
            switch (this.eClass) {
                case eCharacterClass.Barbarian:
                    oCharacter = new ocBarbarian();
                    break;
                case eCharacterClass.Demon_Hunter:
                    oCharacter = new ocDemonHunter();
                    break;
                case eCharacterClass.Monk:
                    oCharacter = new ocMonk();
                    break;
                default:
                    oCharacter = new ocCharacter();
                    break;

            }

            oCharacter.sID = this.sID;
            oCharacter.eClass = this.eClass;
            oCharacter.sName = this.sName;
            oCharacter.iBaseStat_Strength = this.iBaseStat_Strength;
            oCharacter.iBaseStat_Dexterity = this.iBaseStat_Dexterity;
            oCharacter.iBaseStat_Intelligence = this.iBaseStat_Intelligence;
            oCharacter.iBaseStat_Vitality = this.iBaseStat_Vitality;
            oCharacter.fOffStat_AttackSpeedInrease = this.fOffStat_AttackSpeedInrease;
            oCharacter.fOffStat_CritChance = this.fOffStat_CritChance;
            oCharacter.fOffStat_CritDamage = this.fOffStat_CritDamage;
            oCharacter.iOffStat_BonusDamage_Min = this.iOffStat_BonusDamage_Min;
            oCharacter.iOffStat_BonusDamage_Max = this.iOffStat_BonusDamage_Max;
            oCharacter.fWeaponStats_MHDPS = this.fWeaponStats_MHDPS;
            oCharacter.fWeaponStats_MHAPS = this.fWeaponStats_MHAPS;
            oCharacter.iActiveSkills = this.iActiveSkills;
            oCharacter.iPassiveSkills = this.iPassiveSkills;

            if (eClass == eCharacterClass.Barbarian) {
                ((ocBarbarian)oCharacter).bWeaponStat_Dualwield = ((ocBarbarian)this).bWeaponStat_Dualwield;
                ((ocBarbarian)oCharacter).fWeaponStats_OHDPS = ((ocBarbarian)this).fWeaponStats_OHDPS;
                ((ocBarbarian)oCharacter).fWeaponStats_OHAPS = ((ocBarbarian)this).fWeaponStats_OHAPS;
            }
            else if (eClass == eCharacterClass.Demon_Hunter) {
                ((ocDemonHunter)oCharacter).bWeaponStat_Dualwield = ((ocDemonHunter)this).bWeaponStat_Dualwield;
                ((ocDemonHunter)oCharacter).fWeaponStats_OHDPS = ((ocDemonHunter)this).fWeaponStats_OHDPS;
                ((ocDemonHunter)oCharacter).fWeaponStats_OHAPS = ((ocDemonHunter)this).fWeaponStats_OHAPS;
            }
            else if (eClass == eCharacterClass.Monk) {
                ((ocMonk)oCharacter).bWeaponStat_Dualwield = ((ocMonk)this).bWeaponStat_Dualwield;
                ((ocMonk)oCharacter).fWeaponStats_OHDPS = ((ocMonk)this).fWeaponStats_OHDPS;
                ((ocMonk)oCharacter).fWeaponStats_OHAPS = ((ocMonk)this).fWeaponStats_OHAPS;
            }

            return oCharacter;
        }

        public bool Equals(ocCharacter oComparedCharacter) {
            return ocCharacter.CompareCharacter(this, oComparedCharacter);
        }

        public CharacterEventArgs ToCharacterEventArgs() {
            return new CharacterEventArgs { sCharacterID = this.sID, eCharacterClass = this.eClass, sCharacterName = this.sName, oCharacter = this };
        }
    }

    public class CharacterEventArgs : EventArgs {
        public string sCharacterID;
        public string sCharacterName;
        public ocCharacter.eCharacterClass eCharacterClass;
        public ocCharacter oCharacter;
    }
}
